package com.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.demo.mapper.*;
import com.demo.pojo.dto.AdvancedScheduleRequestDTO;
import com.demo.pojo.entity.*;
import com.demo.service.IntelligentScheduleService;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 高级智能排课服务实现类
 * 支持班级选择、课时限制、时间均匀分配、冲突避免和课程选择
 */
public class AdvancedScheduleServiceImpl implements IntelligentScheduleService {
    
    @Autowired
    private ScheduleMapper scheduleMapper;
    
    @Autowired
    private CourseMapper courseMapper;
    
    @Autowired
    private TeacherMapper teacherMapper;
    
    @Autowired
    private ClassroomMapper classroomMapper;
    
    @Autowired
    private ClazzMapper clazzMapper;
    
    @Autowired
    private TimeSlotMapper timeSlotMapper;
    
    @Autowired
    private StudentCourseMapper studentCourseMapper;
    
    @Autowired
    private StudentMapper studentMapper;
    
    @Override
    public boolean executeIntelligentSchedule(String semester) {
        // 使用默认参数执行排课
        AdvancedScheduleRequestDTO request = new AdvancedScheduleRequestDTO();
        request.setSemester(semester);
        return executeAdvancedSchedule(request);
    }
    
    /**
     * 执行高级智能排课
     */
    public boolean executeAdvancedSchedule(AdvancedScheduleRequestDTO request) {
        try {
            System.out.println("开始执行高级智能排课");
            System.out.println("学期：" + request.getSemester());
            System.out.println("选择班级数量：" + (request.getSelectedClazzIds() != null ? request.getSelectedClazzIds().size() : 0));
            System.out.println("选择课程数量：" + (request.getSelectedCourseIds() != null ? request.getSelectedCourseIds().size() : 0));
            System.out.println("每周最大课时：" + request.getMaxPeriodsPerWeek());
            System.out.println("每天最大课时：" + request.getMaxPeriodsPerDay());
            
            // 删除旧的排课记录
            cleanOldSchedules(request);
            
            // 1. 获取选择的课程
            List<Course> courses = getSelectedCourses(request);
            if (courses.isEmpty()) {
                System.out.println("没有找到符合条件的课程");
                return false;
            }
            System.out.println("找到课程数量：" + courses.size());
            
            // 2. 获取选择的班级
            List<Clazz> clazzes = getSelectedClazzes(request);
            if (clazzes.isEmpty()) {
                System.out.println("没有找到符合条件的班级");
                return false;
            }
            System.out.println("找到班级数量：" + clazzes.size());
            
            // 3. 获取可用教室和时间段
            List<Classroom> classrooms = getAvailableClassrooms();
            List<TimeSlot> timeSlots = getAvailableTimeSlots(request.getSemester());
            
            if (classrooms.isEmpty() || timeSlots.isEmpty()) {
                System.out.println("没有找到可用的教室或时间段");
                return false;
            }
            
            // 4. 按教师分组课程
            Map<Long, List<Course>> teacherCourses = courses.stream()
                    .filter(course -> course.getTeacherId() != null)
                    .collect(Collectors.groupingBy(Course::getTeacherId));
            
            System.out.println("教师数量：" + teacherCourses.size());
            
            // 5. 为每个班级创建课时分配计划
            Map<Long, ClassSchedulePlan> classSchedulePlans = createClassSchedulePlans(clazzes, request);
            
            // 6. 执行智能排课
            int successCount = executeSmartScheduling(teacherCourses, classSchedulePlans, classrooms, timeSlots, request);
            
            System.out.println("高级智能排课完成，成功创建排课数量：" + successCount);
            return successCount > 0;
            
        } catch (Exception e) {
            System.err.println("高级智能排课执行失败：" + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }
    
    /**
     * 获取选择的课程
     */
    private List<Course> getSelectedCourses(AdvancedScheduleRequestDTO request) {
        if (request.getSelectedCourseIds() != null && !request.getSelectedCourseIds().isEmpty()) {
            // 如果指定了课程ID，只选择这些课程
            return courseMapper.selectBatchIds(request.getSelectedCourseIds());
        } else {
            // 否则选择所有有教师的课程
            return courseMapper.selectList(
                new QueryWrapper<Course>().isNotNull("teacher_id")
            );
        }
    }
    
    /**
     * 获取选择的班级
     */
    private List<Clazz> getSelectedClazzes(AdvancedScheduleRequestDTO request) {
        if (request.getSelectedClazzIds() != null && !request.getSelectedClazzIds().isEmpty()) {
            // 如果指定了班级ID，只选择这些班级
            return clazzMapper.selectBatchIds(request.getSelectedClazzIds());
        } else {
            // 否则选择所有班级
            return clazzMapper.selectList(null);
        }
    }
    
    /**
     * 获取可用教室
     */
    private List<Classroom> getAvailableClassrooms() {
        QueryWrapper<Classroom> query = new QueryWrapper<>();
        query.eq("status", 1);
        return classroomMapper.selectList(query);
    }
    
    /**
     * 获取可用时间段
     */
    private List<TimeSlot> getAvailableTimeSlots(String semester) {
        QueryWrapper<TimeSlot> query = new QueryWrapper<>();
        query.eq("semester", semester).eq("status", 1);
        return timeSlotMapper.selectList(query);
    }
    
    /**
     * 为每个班级创建课时分配计划
     */
    private Map<Long, ClassSchedulePlan> createClassSchedulePlans(List<Clazz> clazzes, AdvancedScheduleRequestDTO request) {
        Map<Long, ClassSchedulePlan> plans = new HashMap<>();
        
        for (Clazz clazz : clazzes) {
            ClassSchedulePlan plan = new ClassSchedulePlan();
            plan.setClazzId(clazz.getClazzId());
            plan.setClazzName(clazz.getClazzName());
            plan.setMaxPeriodsPerWeek(request.getMaxPeriodsPerWeek());
            plan.setMaxPeriodsPerDay(request.getMaxPeriodsPerDay());
            plan.setEvenDistribution(request.getEvenDistribution());
            
            // 初始化每天的课时分配
            for (int day = 1; day <= 5; day++) { // 周一到周五
                plan.getDailyPeriods().put(day, new ArrayList<>());
            }
            
            plans.put(clazz.getClazzId(), plan);
        }
        
        return plans;
    }
    
    /**
     * 执行智能排课（修复：为每个班级分别排课）
     */
    private int executeSmartScheduling(Map<Long, List<Course>> teacherCourses, 
                                     Map<Long, ClassSchedulePlan> classSchedulePlans,
                                     List<Classroom> classrooms, 
                                     List<TimeSlot> timeSlots,
                                     AdvancedScheduleRequestDTO request) {
        int successCount = 0;
        Random random = new Random();
        
        // 记录每个(课程,班级)已经使用的时段，避免同一课程同一班重复同一时段
        Map<String, Set<Long>> courseClassUsedSlotMap = new HashMap<>();
        
        // 获取需要排课的班级列表
        List<Clazz> targetClazzes = new ArrayList<>();
        for (ClassSchedulePlan plan : classSchedulePlans.values()) {
            Clazz clazz = clazzMapper.selectById(plan.getClazzId());
            if (clazz != null) {
                targetClazzes.add(clazz);
            }
        }
        
        System.out.println("🎯 需要排课的班级数量：" + targetClazzes.size());
        for (Clazz clazz : targetClazzes) {
            System.out.println("  - " + clazz.getClazzName() + " (院系: " + clazz.getDept() + ")");
        }
        
        // 按教师顺序处理课程
        for (Map.Entry<Long, List<Course>> entry : teacherCourses.entrySet()) {
            Long teacherId = entry.getKey();
            List<Course> teacherCourseList = entry.getValue();
            
            Teacher teacher = teacherMapper.selectById(teacherId);
            System.out.println("\n👨‍🏫 为教师 " + (teacher != null ? teacher.getTeName() : "ID:" + teacherId) + " 排课");
            
            // 为每个课程排课
            for (Course course : teacherCourseList) {
                // 🔒 固定每门课每个班每周排2节
                int sessionsPerWeek = 2;
                System.out.println("\n📚 课程 [" + course.getCourseName() + "] 固定每周安排: " + sessionsPerWeek + "节");

                // 为每个班级分别排课
                for (Clazz targetClazz : targetClazzes) {
                    // 🔥 选修课只排到选修班（班级名包含"选修"）
                    if ("选修".equals(course.getCourseType())) {
                        // 检查班级名是否包含"选修"
                        if (targetClazz.getClazzName() == null || !targetClazz.getClazzName().contains("选修")) {
                            System.out.println("  ⊘ 跳过班级 [" + targetClazz.getClazzName() + "]：选修课只能排到选修班");
                            continue;
                        }
                        System.out.println("  📌 选修课 [" + course.getCourseName() + "] 排到选修班 [" + targetClazz.getClazzName() + "]");
                    } else {
                        // 必修课检查课程院系是否匹配班级院系
                        if (course.getDept() != null && !course.getDept().equals(targetClazz.getDept())) {
                            System.out.println("  ⊘ 跳过班级 [" + targetClazz.getClazzName() + "]：院系不匹配 (课程:" + 
                                             course.getDept() + " vs 班级:" + targetClazz.getDept() + ")");
                            continue;
                        }
                        // 必修课不应该排到选修班
                        if (targetClazz.getClazzName() != null && targetClazz.getClazzName().contains("选修")) {
                            System.out.println("  ⊘ 跳过班级 [" + targetClazz.getClazzName() + "]：必修课不能排到选修班");
                            continue;
                        }
                    }
                    
                    System.out.println("  🎓 为班级 [" + targetClazz.getClazzName() + "] 排课：");
                    
                    // 统计该班级该课程的实际排课成功节数
                    int actualScheduled = 0;
                    
                    for (int sessionIndex = 0; sessionIndex < sessionsPerWeek; sessionIndex++) {
                        boolean sessionScheduled = false;
                        
                        // 每节课最多尝试10次
                        for (int attempt = 0; attempt < 10 && !sessionScheduled; attempt++) {
                            // 选择合适的时间段（避免冲突）
                            TimeSlot timeSlot = selectOptimalTimeSlot(timeSlots, teacherId, request);
                            if (timeSlot == null) {
                                System.out.println("    ⚠️ 第" + (sessionIndex + 1) + "节：找不到可用时间段（尝试" + (attempt + 1) + "/10）");
                                continue;
                            }

                            // 检查该班级在该时段是否有冲突
                            if (isClassTimeConflict(targetClazz.getClazzId(), timeSlot)) {
                                continue; // 班级时间冲突，重试
                            }
                            
                            // 🔥 如果是选修课，检查选课学生的个人必修课时间冲突
                            if ("选修".equals(course.getCourseType())) {
                                if (isElectiveStudentTimeConflict(course.getCourseId(), timeSlot)) {
                                    continue; // 选课学生有必修课冲突，重试
                                }
                            }

                            // 避免同一课程同一班重复相同时段
                            String key = course.getCourseId() + ":" + targetClazz.getClazzId();
                            Set<Long> usedSet = courseClassUsedSlotMap.computeIfAbsent(key, k -> new HashSet<>());
                            if (usedSet.contains(timeSlot.getTimeSlotId())) {
                                continue; // 已使用的时段，重试
                            }

                            // 检查该班级的课时限制
                            ClassSchedulePlan plan = classSchedulePlans.get(targetClazz.getClazzId());
                            if (plan != null && !canAssignToClass(plan, timeSlot.getDayOfWeek(), request)) {
                                continue; // 超过课时限制，重试
                            }

                            // 选择合适的教室
                            Classroom classroom = selectOptimalClassroom(course, classrooms, timeSlot, request);
                            if (classroom == null) {
                                System.out.println("    ⚠️ 第" + (sessionIndex + 1) + "节：找不到可用教室（尝试" + (attempt + 1) + "/10）");
                                continue;
                            }

                            // 创建排课记录
                            Schedule schedule = createSchedule(course, teacher, classroom, targetClazz, timeSlot, request);

                            try {
                                scheduleMapper.insert(schedule);
                                successCount++;
                                actualScheduled++;
                                if (plan != null) {
                                    updateClassSchedulePlan(plan, timeSlot);
                                }
                                usedSet.add(timeSlot.getTimeSlotId());
                                sessionScheduled = true; // 标记成功
                                System.out.println("    ✓ 第" + (sessionIndex + 1) + "/" + sessionsPerWeek + "节：" + 
                                                 classroom.getClassroomName() +
                                                 " - 星期" + timeSlot.getDayOfWeek() + " 第" + timeSlot.getPeriodNo() + "节");
                            } catch (Exception e) {
                                System.err.println("    ✗ 插入数据库失败：" + e.getMessage());
                                continue; // 数据库错误，重试
                            }
                        }
                        
                        if (!sessionScheduled) {
                            System.out.println("    ✗ 第" + (sessionIndex + 1) + "节排课失败（已尝试10次）");
                        }
                    }
                    
                    // 输出该班级该课程的排课结果总结
                    if (actualScheduled < sessionsPerWeek) {
                        System.out.println("  ⚠️ 班级 [" + targetClazz.getClazzName() + "] 课程 [" + course.getCourseName() + "] 排课不完整！" +
                                         " 应排: " + sessionsPerWeek + "节，实际排: " + actualScheduled + "节");
                    } else {
                        System.out.println("  ✅ 班级 [" + targetClazz.getClazzName() + "] 课程 [" + course.getCourseName() + "] 排课完成！" +
                                         " 应排: " + sessionsPerWeek + "节，实际排: " + actualScheduled + "节");
                    }
                }
            }
        }
        
        System.out.println("\n🎉 排课总结：共成功创建 " + successCount + " 条排课记录");
        return successCount;
    }
    
    /**
     * 选择最优时间段
     */
    private TimeSlot selectOptimalTimeSlot(List<TimeSlot> timeSlots,
                                         Long teacherId, AdvancedScheduleRequestDTO request) {
        // 基于全量可用时段进行选择
        List<TimeSlot> availableSlots = new ArrayList<>(timeSlots);
        
        if (availableSlots.isEmpty()) {
            return null;
        }
        
        // 如果启用教师冲突避免，检查教师时间冲突
        if (request.getAvoidTeacherConflict()) {
            availableSlots = availableSlots.stream()
                    .filter(slot -> !isTeacherTimeConflict(teacherId, slot))
                    .collect(Collectors.toList());
        }
        
        if (availableSlots.isEmpty()) {
            return null;
        }
        
        // 随机选择一个可用时间段
        Random random = new Random();
        return availableSlots.get(random.nextInt(availableSlots.size()));
    }
    
    /**
     * 选择教室（随机选择可用教室，不按类型分类）
     */
    private Classroom selectOptimalClassroom(Course course, List<Classroom> classrooms, 
                                           TimeSlot timeSlot,
                                           AdvancedScheduleRequestDTO request) {
        // 🔥 用户需求：随机选择教室，不按类型分类
        List<Classroom> availableClassrooms = new ArrayList<>(classrooms);
        
        // 如果启用教室冲突避免，过滤掉已被占用的教室
        if (request.getAvoidClassroomConflict()) {
            availableClassrooms = availableClassrooms.stream()
                    .filter(classroom -> !isClassroomTimeConflict(classroom.getClassroomId(), timeSlot))
                    .collect(Collectors.toList());
        }
        
        if (availableClassrooms.isEmpty()) {
            return null;
        }
        
        // 随机选择一个可用教室
        Random random = new Random();
        return availableClassrooms.get(random.nextInt(availableClassrooms.size()));
    }
    
    /**
     * 选择最优班级
     */
    private Clazz selectOptimalClass(Course course, Map<Long, ClassSchedulePlan> classSchedulePlans, 
                                   TimeSlot timeSlot, AdvancedScheduleRequestDTO request) {
        String courseDept = course.getDept();
        int dayOfWeek = timeSlot.getDayOfWeek();
        
        // 优先选择同院系且满足课时限制的班级
        List<Clazz> suitableClazzes = new ArrayList<>();
        
        for (ClassSchedulePlan plan : classSchedulePlans.values()) {
            // 检查是否同院系
            Clazz clazz = clazzMapper.selectById(plan.getClazzId());
            if (clazz != null && courseDept.equals(clazz.getDept())) {
                // 检查课时限制
                if (canAssignToClass(plan, dayOfWeek, request)) {
                    suitableClazzes.add(clazz);
                }
            }
        }
        
        // 如果没有同院系的合适班级，选择任何满足条件的班级
        if (suitableClazzes.isEmpty()) {
            for (ClassSchedulePlan plan : classSchedulePlans.values()) {
                Clazz clazz = clazzMapper.selectById(plan.getClazzId());
                if (clazz != null && canAssignToClass(plan, dayOfWeek, request)) {
                    suitableClazzes.add(clazz);
                }
            }
        }
        
        if (suitableClazzes.isEmpty()) {
            return null;
        }
        
        Random random = new Random();
        return suitableClazzes.get(random.nextInt(suitableClazzes.size()));
    }
    
    /**
     * 检查是否可以分配给班级
     */
    private boolean canAssignToClass(ClassSchedulePlan plan, int dayOfWeek, AdvancedScheduleRequestDTO request) {
        // 检查每周课时限制
        int weeklyPeriods = plan.getDailyPeriods().values().stream()
                .mapToInt(List::size)
                .sum();
        if (weeklyPeriods >= plan.getMaxPeriodsPerWeek()) {
            return false;
        }
        
        // 检查每天课时限制
        List<Long> dailyPeriods = plan.getDailyPeriods().get(dayOfWeek);
        if (dailyPeriods.size() >= plan.getMaxPeriodsPerDay()) {
            return false;
        }
        
        return true;
    }
    
    /**
     * 更新班级课时计划
     */
    private void updateClassSchedulePlan(ClassSchedulePlan plan, TimeSlot timeSlot) {
        int dayOfWeek = timeSlot.getDayOfWeek();
        plan.getDailyPeriods().get(dayOfWeek).add(timeSlot.getTimeSlotId());
    }
    
    /**
     * 创建排课记录
     */
    private Schedule createSchedule(Course course, Teacher teacher, Classroom classroom, 
                                  Clazz clazz, TimeSlot timeSlot, AdvancedScheduleRequestDTO request) {
        Schedule schedule = new Schedule();
        schedule.setCourseId(course.getCourseId());
        schedule.setTeacherId(course.getTeacherId());
        schedule.setClassroomId(classroom.getClassroomId());
        schedule.setTimeSlotId(timeSlot.getTimeSlotId());
        schedule.setClazzId(clazz.getClazzId());
        schedule.setScheduleType("正常");
        schedule.setStatus("ACTIVE");
        schedule.setPriority(request.getPriority());
        schedule.setIsFixed(0);
        schedule.setScheduleRemark(request.getRemark());
        schedule.setCreateTime(new Date());
        schedule.setUpdateTime(new Date());
        return schedule;
    }
    
    /**
     * 检查教师时间冲突
     */
    private boolean isTeacherTimeConflict(Long teacherId, TimeSlot timeSlot) {
        QueryWrapper<Schedule> query = new QueryWrapper<>();
        query.eq("teacher_id", teacherId)
             .eq("time_slot_id", timeSlot.getTimeSlotId());
        return scheduleMapper.selectCount(query) > 0;
    }
    
    /**
     * 检查教室时间冲突
     */
    private boolean isClassroomTimeConflict(Long classroomId, TimeSlot timeSlot) {
        QueryWrapper<Schedule> query = new QueryWrapper<>();
        query.eq("classroom_id", classroomId)
             .eq("time_slot_id", timeSlot.getTimeSlotId());
        return scheduleMapper.selectCount(query) > 0;
    }
    
    /**
     * 检查班级时间冲突
     */
    private boolean isClassTimeConflict(Long clazzId, TimeSlot timeSlot) {
        QueryWrapper<Schedule> query = new QueryWrapper<>();
        query.eq("clazz_id", clazzId)
             .eq("time_slot_id", timeSlot.getTimeSlotId());
        return scheduleMapper.selectCount(query) > 0;
    }
    
    /**
     * 🔥 检查选修课学生的个人必修课时间冲突
     * 
     * @param courseId 选修课程ID
     * @param timeSlot 拟安排的时间段
     * @return true表示有冲突，false表示无冲突
     */
    private boolean isElectiveStudentTimeConflict(Long courseId, TimeSlot timeSlot) {
        // 1. 查询已选择该选修课的学生列表
        QueryWrapper<StudentCourse> scWrapper = new QueryWrapper<>();
        scWrapper.eq("course_id", courseId)
                 .eq("status", "SELECTED");  // 只查询已审核通过的学生
        List<StudentCourse> selectedStudents = studentCourseMapper.selectList(scWrapper);
        
        if (selectedStudents.isEmpty()) {
            // 如果还没有学生选课，不需要检查冲突
            System.out.println("      📌 选修课暂无学生选课，跳过个人冲突检查");
            return false;
        }
        
        System.out.println("      📌 检查 " + selectedStudents.size() + " 个选课学生的必修课冲突...");
        
        // 2. 获取这些学生的班级ID
        Set<Long> studentIds = selectedStudents.stream()
                .map(StudentCourse::getStudentId)
                .collect(Collectors.toSet());
        
        // 3. 查询学生信息，获取他们的班级ID
        List<Student> students = studentMapper.selectBatchIds(studentIds);
        Set<Long> clazzIds = students.stream()
                .map(Student::getClazzId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        
        if (clazzIds.isEmpty()) {
            System.out.println("      ⚠️ 选课学生没有关联班级，跳过冲突检查");
            return false;
        }
        
        // 4. 检查这些班级在该时间段是否有必修课
        for (Long clazzId : clazzIds) {
            QueryWrapper<Schedule> scheduleWrapper = new QueryWrapper<>();
            scheduleWrapper.eq("clazz_id", clazzId)
                          .eq("time_slot_id", timeSlot.getTimeSlotId());
            
            List<Schedule> existingSchedules = scheduleMapper.selectList(scheduleWrapper);
            
            if (!existingSchedules.isEmpty()) {
                // 检查这些课程是否为必修课
                for (Schedule existingSchedule : existingSchedules) {
                    Course existingCourse = courseMapper.selectById(existingSchedule.getCourseId());
                    if (existingCourse != null && "必修".equals(existingCourse.getCourseType())) {
                        // 找到班级名称用于日志
                        Clazz clazz = clazzMapper.selectById(clazzId);
                        String clazzName = clazz != null ? clazz.getClazzName() : "ID:" + clazzId;
                        
                        System.out.println("      ❌ 时间冲突！班级 [" + clazzName + "] 在该时段有必修课: " + 
                                         existingCourse.getCourseName());
                        return true; // 有冲突
                    }
                }
            }
        }
        
        System.out.println("      ✅ 无必修课冲突");
        return false; // 无冲突
    }
    
    /**
     * 🔥 清理旧的排课记录
     * 删除本次排课涉及的班级和课程的旧排课，避免重复
     */
    private void cleanOldSchedules(AdvancedScheduleRequestDTO request) {
        System.out.println("\n=== 清理旧排课记录 ===");
        
        // 获取本次排课的班级ID和课程ID
        List<Long> clazzIds = request.getSelectedClazzIds();
        List<Long> courseIds = request.getSelectedCourseIds();
        String semester = request.getSemester();
        
        // 构建删除条件
        QueryWrapper<Schedule> deleteWrapper = new QueryWrapper<>();
        boolean hasCondition = false;
        
        // 如果指定了班级，删除这些班级的排课
        if (clazzIds != null && !clazzIds.isEmpty()) {
            deleteWrapper.in("clazz_id", clazzIds);
            hasCondition = true;
            System.out.println("📌 删除条件：班级ID = " + clazzIds);
        }
        
        // 如果指定了课程，删除这些课程的排课
        if (courseIds != null && !courseIds.isEmpty()) {
            deleteWrapper.in("course_id", courseIds);
            hasCondition = true;
            System.out.println("📌 删除条件：课程ID = " + courseIds);
        }
        
        // 如果指定了学期，只删除该学期的排课
        if (semester != null && !semester.isEmpty() && !semester.equals("advanced")) {
            // 查询该学期的 time_slot_id
            QueryWrapper<TimeSlot> tsWrapper = new QueryWrapper<>();
            tsWrapper.eq("semester", semester);
            List<TimeSlot> timeSlots = timeSlotMapper.selectList(tsWrapper);
            
            if (!timeSlots.isEmpty()) {
                List<Long> timeSlotIds = timeSlots.stream()
                        .map(TimeSlot::getTimeSlotId)
                        .collect(Collectors.toList());
                deleteWrapper.in("time_slot_id", timeSlotIds);
                System.out.println("📌 删除条件：学期 = " + semester);
            }
        }
        
        // 执行删除
        if (hasCondition) {
            int deletedCount = scheduleMapper.delete(deleteWrapper);
            System.out.println("🗑️ 删除旧排课记录: " + deletedCount + " 条");
        } else {
            System.out.println("⚠️ 没有指定删除条件，跳过清理");
        }
        
        System.out.println("=== 清理完成 ===\n");
    }
    
    @Override
    public boolean checkConstraints(Schedule schedule) {
        return true;
    }
    
    @Override
    public List<Schedule> optimizeSchedule(List<Schedule> schedules) {
        return schedules;
    }
    
    @Override
    public boolean resolveConflicts(List<Schedule> schedules) {
        return true;
    }
    
    @Override
    public double calculateScheduleQuality(List<Schedule> schedules) {
        return 0.95; // 高级排课质量最高
    }
    
    /**
     * 获取可选择的班级列表
     */
    public List<Clazz> getAvailableClazzes() {
        return clazzMapper.selectList(null);
    }
    
    /**
     * 获取可选择的课程列表
     */
    public List<Course> getAvailableCourses() {
        return courseMapper.selectList(
            new QueryWrapper<Course>().isNotNull("teacher_id")
        );
    }
    
    /**
     * 班级课时计划内部类
     */
    private static class ClassSchedulePlan {
        private Long clazzId;
        private String clazzName;
        private Integer maxPeriodsPerWeek;
        private Integer maxPeriodsPerDay;
        private Boolean evenDistribution;
        private Map<Integer, List<Long>> dailyPeriods = new HashMap<>(); // 每天的课时ID列表
        
        // Getters and Setters
        public Long getClazzId() { return clazzId; }
        public void setClazzId(Long clazzId) { this.clazzId = clazzId; }
        
        public String getClazzName() { return clazzName; }
        public void setClazzName(String clazzName) { this.clazzName = clazzName; }
        
        public Integer getMaxPeriodsPerWeek() { return maxPeriodsPerWeek; }
        public void setMaxPeriodsPerWeek(Integer maxPeriodsPerWeek) { this.maxPeriodsPerWeek = maxPeriodsPerWeek; }
        
        public Integer getMaxPeriodsPerDay() { return maxPeriodsPerDay; }
        public void setMaxPeriodsPerDay(Integer maxPeriodsPerDay) { this.maxPeriodsPerDay = maxPeriodsPerDay; }
        
        public Boolean getEvenDistribution() { return evenDistribution; }
        public void setEvenDistribution(Boolean evenDistribution) { this.evenDistribution = evenDistribution; }
        
        public Map<Integer, List<Long>> getDailyPeriods() { return dailyPeriods; }
        public void setDailyPeriods(Map<Integer, List<Long>> dailyPeriods) { this.dailyPeriods = dailyPeriods; }
    }
}


